﻿using System.Reflection;
using ApiLib.RCL.Components.AutoTable.Attributes;
using ApiLib.RCL.Components.AutoTable.Models;
using ApiLib.RCL.Models;
using ApiLib.RCL.Utils;
using BootstrapBlazor.Components;
using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop;

namespace ApiLib.RCL.Components.AutoTable;

/// <summary>
/// 表格增强版
/// </summary>
/// <typeparam name="TItem"></typeparam>
public partial class AutoTable<TItem> : ComponentBase
    where TItem : IAutoTable<TItem>, new()
{
    /// <summary>
    /// 
    /// </summary>
    private TableAttribute _tableAttribute = new();

    /// <summary>
    /// 查询参数
    /// </summary>
    private Dictionary<ColumnAttribute, PropertyInfo> _searchColumns = new();

    private Table<TItem> _table;
    
    /// <summary>
    /// 实体对象
    /// </summary>
    public readonly TItem Entity = new();
    private readonly Dictionary<ColumnAttribute, PropertyInfo> _listColumns = new();
    private readonly Dictionary<string, object> _param = new();

    [Inject] private DialogService dialog { get; set; }
    [Inject] private SwalService swal { get; set; }
    [Inject] private MessageService message { get; set; }
    [Inject] private IJSRuntime js { get; set; }
    [Inject] private DownloadService download { get; set; }

    /// <summary>
    /// 表格初始化完成后回调
    /// </summary>
    [Parameter]
    public Func<TableAttribute, Task>? OnTableInitialized { get; set; } = null;

    /// <summary>
    /// 行操作按钮
    /// </summary>
    [Parameter]
    public RenderFragment<TItem>? RowButtonTemplate { get; set; }

    /// <summary>
    /// 头部操作按钮
    /// </summary>
    [Parameter]
    public RenderFragment? HeaderButtonTemplate { get; set; }
    /// <summary>
    /// 显示默认行按钮，默认true
    /// </summary>
    [Parameter]
    public bool ShowDefaultRowButtons { get; set; } = true;

    private Modal _importModal;

    private ListResponse<TItem> ListResponse { get; set; } = new();
    private bool _isLoading = false;

    private int _showColumnCount = 0;

    private int _pageIndex=1;
    private int _pageSize = 0;
    private int _pageCount = 0;
    // private string _pageInfoText => $"每页 {_pageSize} 条 共 {_pageCount} 页";
    private string _pageInfoText => $"{1+(_pageIndex-1)*_pageSize} - {_pageIndex*_pageSize} 共 {ListResponse.TotalCount} 条";

    /// <summary>
    /// 初始化
    /// </summary>
    protected override async Task OnInitializedAsync()
    {
        var tableAttribute = Entity.GetTableAttribute();
        if (tableAttribute != null)
        {
            _tableAttribute = tableAttribute;
        }

        if (string.IsNullOrEmpty(_tableAttribute.Name))
        {
            _tableAttribute.Name = typeof(TItem).Name;
        }

        if (OnTableInitialized != null)
        {
            await OnTableInitialized.Invoke(_tableAttribute);
        }

        var properties = typeof(TItem).GetProperties();
        foreach (var propertyInfo in properties)
        {
            var columnAttribute = propertyInfo.GetCustomAttribute<ColumnAttribute>();

            if (_tableAttribute.UseDefaultColumn && columnAttribute == null)
            {
                columnAttribute = new ColumnAttribute();
            }

            if (columnAttribute != null)
            {
                if (columnAttribute.ShowOnSearch)
                {
                    
                    columnAttribute.InitSearchObject();
                    _searchColumns[columnAttribute] = propertyInfo;
                }

                if (columnAttribute.ShowOnList)
                {
                    _listColumns[columnAttribute] = propertyInfo;
                    if (string.IsNullOrEmpty(columnAttribute.Name))
                    {
                        columnAttribute.Name = propertyInfo.Name;
                    }
                }
            }
        }

        _showColumnCount = _listColumns.Count + (_tableAttribute.ShowLineNo ? 1 : 0) + 1;
        _pageSize = _tableAttribute.PageItemsSource[0];
        await ToSearch();
    }

    private async Task<QueryData<TItem>> OnQueryAsync(QueryPageOptions arg)
    {
        foreach (var (key, value) in _searchColumns)
        {
            key.AddSearchParam(value.Name, _param);
        }

        _param["pageIndex"] = arg.PageIndex;
        _param["pageSize"] = arg.PageIndex;
        var res = await Entity.OnQuery(_param);
        return new QueryData<TItem>()
        {
            Items = res?.data?.List ?? new List<TItem>(),
            TotalCount = res?.data?.TotalCount ?? 0,
        };
    }
    
    private async Task OnPageItemsValueChanged(int arg)
    {
        _pageSize = arg;
        await OnPageLinkClick(1);
    }

    private async Task OnPageLinkClick(int pageIndex)
    {
        _pageIndex = pageIndex;
        _isLoading = true;
        StateHasChanged();
        foreach (var (key, value) in _searchColumns)
        {
            key.AddSearchParam(value.Name, _param);
        }

        _param["pageIndex"] = pageIndex;
        _param["pageSize"] = _pageSize;
        var res = await Entity.OnQuery(_param);
        ListResponse = res?.data ?? new();
        _pageCount = ListResponse.TotalCount % _pageSize == 0
            ? ListResponse.TotalCount / _pageSize
            : ListResponse.TotalCount / _pageSize + 1;
        _isLoading = false;
        StateHasChanged();
    }

    /// <summary>
    /// 查询
    /// </summary>
    public async Task ToSearch()
    {
        // await _table.QueryAsync(1);
        await OnPageLinkClick(1);
    }

    /// <summary>
    /// 新增
    /// </summary>
    public async Task ToAdd()
    {
        await dialog.ShowDialog<AutoTableDetailComponent<TItem>>("新增", _tableAttribute.DialogSize,
            new Dictionary<string, object?>()
            {
                [nameof(AutoTableDetailComponent<TItem>.Entity)] = new TItem(),
                [nameof(AutoTableDetailComponent<TItem>.IsOutline)] = _tableAttribute.IsOutline,
                [nameof(AutoTableDetailComponent<TItem>.IsDisabled)] = false,
            }, async () => { await ToSearch(); });
    }

    /// <summary>
    /// 打开详情
    /// </summary>
    /// <param name="info"></param>
    public async Task ToDetail(TItem info)
    {
        await dialog.ShowDialog<AutoTableDetailComponent<TItem>>("详情", _tableAttribute.DialogSize,
            new Dictionary<string, object?>()
            {
                [nameof(AutoTableDetailComponent<TItem>.Entity)] = info,
                [nameof(AutoTableDetailComponent<TItem>.IsOutline)] = _tableAttribute.IsOutline,
                [nameof(AutoTableDetailComponent<TItem>.IsDisabled)] = true,
            });
    }

    /// <summary>
    /// 打开编辑
    /// </summary>
    /// <param name="info"></param>
    public async Task ToEdit(TItem info)
    {
        await dialog.ShowDialog<AutoTableDetailComponent<TItem>>("编辑", _tableAttribute.DialogSize,
            new Dictionary<string, object?>()
            {
                [nameof(AutoTableDetailComponent<TItem>.Entity)] = info,
                [nameof(AutoTableDetailComponent<TItem>.IsOutline)] = _tableAttribute.IsOutline,
                [nameof(AutoTableDetailComponent<TItem>.IsDisabled)] = false,
            }, async () => { await ToSearch(); });
    }

    /// <summary>
    /// 删除
    /// </summary>
    /// <param name="info"></param>
    public async Task ToDelete(TItem info)
    {
        var sweetModal = await swal.SweetModal("确定删除吗？", "删除后不可恢复");
        if (sweetModal)
        {
            var response = await info.OnDelete();
            if (response is { code: 0 ,data:true})
            {
                await NotifySuccess("删除成功");
                await ToSearch();
            }
            else
            {
                await NotifyWarning(response?.msg ?? "删除失败");
            }
        }
    }

    public async Task ToExport()
    {
        foreach (var (key, value) in _searchColumns)
        {
            key.AddSearchParam(value.Name, _param);
        }

        var stream = await Entity.OnExport(_param);
        if (stream == null)
        {
            await NotifyWarning("导出失败");
            return;
        }

        await download.DownloadFromStreamAsync($"{_tableAttribute.Name}{DateTime.Now:_yyyy-MM-dd}.xlsx", stream);
        await NotifySuccess("导出成功");
    }

    public async Task ToExportTemplate()
    {
        var stream = await Entity.OnExportTemplate();
        if (stream == null)
        {
            await NotifyWarning("导出失败");
            return;
        }

        await download.DownloadFromStreamAsync($"{_tableAttribute.Name}导入模板.xlsx", stream);
        await NotifySuccess("导出成功");
    }

    public async Task ToImportModel()
    {
        await _importModal.Toggle();
    }

    /// <summary>
    /// 导入
    /// </summary>
    public async Task ToImport(UploadFile file)
    {
        if (file.File != null)
        {
            var response = await Entity.OnImport(file.File);
            if (response is { code: 0 ,data: true})
            {
                await NotifySuccess("导入成功");
                await _importModal.Toggle();
                await ToSearch();
            }
            else
            {
                await NotifyWarning(response?.msg ?? "导入失败");
            }
        }
    }
    /// <summary>
    /// 警告
    /// </summary>
    /// <param name="content"></param>
    public async Task NotifyWarning(string content)
    {
        if (_tableAttribute.IsSwalNotify)
        {
            await swal.SweetWarning("提示", content);
        }
        else
        {
            await message.MessageWarning(content);
        }
    }
    
    /// <summary>
    /// 成功
    /// </summary>
    /// <param name="content"></param>
    public async Task NotifySuccess(string content)
    {
        if (_tableAttribute.IsSwalNotify)
        {
            await swal.SweetSuccess("成功", content);
        }
        else
        {
            await message.MessageSuccess(content);
        }
    }
}